package com.scd.boot.request;

import com.scd.boot.exception.ReadInputStreamError;
import jakarta.servlet.ReadListener;
import jakarta.servlet.ServletInputStream;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletRequestWrapper;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;

public class ServletRequestCopyWrapper extends HttpServletRequestWrapper {
    private byte[] bodyParam;

    public ServletRequestCopyWrapper(HttpServletRequest request) {
        super(request);
        bodyParam = readRequest(request);
    }

    private byte[] readRequest(HttpServletRequest request) {
        try {
            InputStream inputStream = request.getInputStream();
            int readLen;
            byte[] buffer = new byte[1024];
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            while ((readLen = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, readLen);
            }
            return outputStream.toByteArray();
        } catch (IOException e) {
            throw new ReadInputStreamError("read input stream error ", e);
        }
    }

    @Override
    public BufferedReader getReader() {
        return new BufferedReader(new InputStreamReader(getInputStream()));
    }

    @Override
    public ServletInputStream getInputStream() {
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bodyParam);
        return new ServletInputStream() {
            @Override
            public boolean isFinished() {
                return false;
            }

            @Override
            public boolean isReady() {
                return false;
            }

            @Override
            public void setReadListener(ReadListener readListener) {
            }

            @Override
            public int read() throws IOException {
                return byteArrayInputStream.read();
            }
        };
    }

    public byte[] getBodyParam() {
        return bodyParam;
    }

    public String getBodyParamStr() {
        return new String(bodyParam, StandardCharsets.UTF_8);
    }
}
